package personal.wang.cli;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import personal.wang.domain.TestpointInfoProto;
import personal.wang.handler.CliMessageHander;
import personal.wang.message.Header;
import personal.wang.message.Message;
import personal.wang.message.MessageDecoder;
import personal.wang.message.MessageEncoder;
import personal.wang.enm.MessageType;
import personal.wang.util.ParameterUtil;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

/**
 * @className: CliFrondend
 * @Description: 命令的格式：
 * deploy.sh: 项目部署的脚本。
 * data-mock.sh: 启动任务的脚本。脚本的参数如下：
 * 1. bash data-mock.sh worker-info
 * 2. bash data-mock.sh task-info
 * 3. bash data-mock.sh submit --path 测试模板路径
 * @Author: wangyifei
 * @Date: 2025/2/14 15:13
 */
public class CliFrondend {
    private static Logger logger = LoggerFactory.getLogger(CliFrondend.class);

    public static void main(String[] args) throws InterruptedException {
        if(args.length == 0) return;
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.option(ChannelOption.SO_RCVBUF , 65536);
        bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR,new FixedRecvByteBufAllocator(1024*10));
        NioEventLoopGroup group = new NioEventLoopGroup();
        Channel client = bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new MessageEncoder());
                        ch.pipeline().addLast(new MessageDecoder());
                        ch.pipeline().addLast(new CliMessageHander());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8082))
                .sync().channel();
        try{
            if (!StringUtils.equalsAny(args[0] , new String[]{"submit" , "task-info" , "worker-info"})) {
                ChannelFuture closeFuture = client.closeFuture();
                closeFuture.sync();
                group.shutdownGracefully();
            }
            Header header = null ;
            Message message = null ;
            if("submit".equals(args[0])){
                String path = ParameterUtil.fromArgument(args).getProperty("path");
                List<TestpointInfoProto.TestPointInfo> parser = CliParameterParser.parser(path);
                for (TestpointInfoProto.TestPointInfo testPointInfo : parser) {
                    int serializedSize = testPointInfo.getSerializedSize();
                    logger.info("serializedSize: {}" , serializedSize);
                    header = new Header(1 , 36
                            , serializedSize
                            , UUID.randomUUID().toString()
                            , MessageType.TO_WORKER_COMMAND_MESSAGE.getFlag());
                    message = new Message(header , testPointInfo.toByteArray());
                }
            }else if("task-info".equals(args[0])){
                byte[] bytes = "task-info".getBytes(StandardCharsets.UTF_8);
                header = new Header(1 , 36
                        ,bytes.length
                        , UUID.randomUUID().toString()
                        , MessageType.WORKER_INFO_COMMAND_MESSAGE.getFlag());
                message = new Message(header , bytes);

            }else if("worker-info".equals(args[0])){
                byte[] bytes = "worker-info".getBytes(StandardCharsets.UTF_8);
                header = new Header(1 , 36
                        ,bytes.length
                        , UUID.randomUUID().toString()
                        , MessageType.WORKER_INFO_COMMAND_MESSAGE.getFlag());
                message = new Message(header , bytes);
            }
            client.writeAndFlush(message);
        }catch (Exception e){
            logger.error("{}" , e.getMessage());
        }
        ChannelFuture closeFuture = client.closeFuture();
        closeFuture.sync();
        group.shutdownGracefully();
    }
}